/* Copyright (C) 2010 Fredrique Samuels, fredriquesamuels@gmail.com 

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef TRI_UTILS_H_
#define TRI_UTILS_H_

#include <stdlib.h>
#include <time.h>
#include <iostream>
#include <stdio.h>
#include <string>
#include <cctype>
#include <vector>
#include <map>
#include <math.h>

#ifdef WIN32
#include <windows.h>
#include <winbase.h>
#else
#include <unistd.h>
#include <stdarg.h>
#endif

namespace tri{

class TVector;

namespace utils{

/**
 * Genrate an integer between min and max 
 */
int random(int min, int max);

/**
 * Generate a floating point number between
 * min and max. prec is the number of possible
 * values to be returned.
 */
float randomFloat(float min, float max, int prec = 1000);

/**
 * Return a tri::TVector(randomFloat(minx,maxx,prec),randomFloat(miny,maxy,prec),randomFloat(minz,maxz,prec))
 */
tri::TVector randomVector(float minx, float maxx,
					float miny, float maxy,
					float minz, float maxz,
					int prec = 1000);

tri::TVector randomVector(tri::TVector min,
		tri::TVector max,
					int prec = 1000);
/**
 * Do a system sleep for x amount of 
 * milli seconds
 * 
 * @param milli : Time to sleep in milli seconds
 */
void sleep(long milli);

/**
 * Returns true if the integer a is a power of 2
 */
bool isPow2(int a);

/**
 * Returns the next integer larger than a that is
 * a power of 2. Return a if a is a power of 2
 */
int nextPow2(int a);

/**
 * Quit the current application
 */
void quit();

/**
 * Convert the given string to an integer values
 */
int string2Int(const char * s );

/**
 * Convert the given float to a 
 * string. 
 */
float string2Float(const char * s);

/**
 * Returns the long value of the string 's'
 */
long string2Long(const char * s);

/**
 * Return the string value of the int a of base value b.
 * base defaults to 10
 * 
 * Ex int2String (15, 10) : 15
 *    int2String (15, 16) : F
 */
std::string int2String(int a,int base = 10);

/**
 * Convert float to string
 */
std::string float2String(float a);

/**
 * Return true the the string n is 
 * a number.
 */
bool isNumber(std::string n);

/**
 * Converts all the characters in string a to uppercase
 */
std::string toUpper(std::string a);

/**
 * Splits a string 'str' at the character c 
 * and stores the result in the list split_str.
 */
void split(std::vector<std::string>& split_str,std::string str,char c);

/**
 * Convert a radian value to degrees. 
 */
float radToDeg(float rad);

/**
 * Convert degress to radian
 */
float degToRad(float deg);

/**
 * Get the absolute value of a given value
 */
float ABS(float v);

/**
 * Get the formatted string
 * 
 * Ex. getFormatString("Hello %s %s", "James", "Hen") : "Hello James Hen"
 */
std::string getFormatString(const char* fmt,...);

/**
 * Returns true if the a starts with the string pref.
 */
bool startsWith(std::string a,std::string pref);


/**
 * Get the largest value btweeen f1 and f2
 */
float max(float f1,float f2);


/**
 * Basic Bubble Sort Algoritm for sorting an array of unsigned int 
 * in set of 4 in ascending order. Order is detrermined by the 
 * index given by hotIndex .
 * 
 * @param a : start of array
 * @param size : Size of the array. Must be a multiple of 4.
 * @param hotIndex : Index that determines the groups position in the array.
 *         valued from 0-3.
 *               
 */
void bubbleSortList4Uint32(unsigned int *a,int size,int hotIndex=0);

/**
 * @see bubble_sort_list_4_uint32
 * 
 * Orders by decending.
 */
void bubbleSortList4Uint32Decend(unsigned int *a,int size,int hotIndex=0);

/**
 * Fit a rectangle to a given aspectratio 
 */
void fitToArea(float src_w,float src_h,float dst_ar,float &dst_w, float &dst_h);

}
}

#endif /*UTILS_H_*/
